﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace xboxssbeatemup
{
    class TBShootProjectile : TriggerableBehavior
    {
        public GameObject[] projectiles;
        public float projectilePower = 6.0f;
        public float muzzleOffset = 0.0f;
        public float range = 1000.0f;

        /// <summary>Construct TBShootProjectile Behavior</summary>
        /// <param name="game">The main Game object. You can just use "this".</param>
        /// <param name="t">Target GameObject that will be shooting the projectile.</param>
        /// <param name="objects">Additional parameters: If of type PlayerIndex, specifies Player to trigger behavior. 
        /// If Buttons, choose GamePad button as trigger. If Keys, choose Keyboard key as trigger.
        /// If GameObject[], set array of GameObjects to act as projectile.</param>
        public TBShootProjectile(Game game, GameObject t, params Object[] objects)
            : base(game, t, objects)
        {
            foreach (Object o in objects)
            {
                // If one of the parameters is an array of GameObjects, it must be the projectile array
                if (o is GameObject[])
                {
                    projectiles = (GameObject[])o;
                }
            }
        }

        public override void Update(GameTime gameTime)
        {
            foreach (GameObject projectile in projectiles)
            {
                // If projectile is alive, move it. If it out of range, kill it. If it is in range, check collisions.
                if (projectile.alive)
                {
                    projectile.position += projectile.velocity;
                    if (projectile.position.Z < this.target.position.Z - range || projectile.position.Z > this.target.position.Z + range || projectile.position.X < this.target.position.X - range || projectile.position.X > this.target.position.X + range)
                    {
                        projectile.alive = false;
                    }
                    else
                    {
                        //TestCollision(projectile);
                    }
                }
            }

            base.Update(gameTime);
        }

        public override void Fire()
        {
            foreach (GameObject projectile in projectiles)
            {
                // Pick the first "dead" projectile, set it to alive and initialize it's velocity/position/rotation
                if (!projectile.alive)
                {
                    //soundBank.PlayCue("missilelaunch");

                    projectile.velocity = GetProjectileMuzzleVelocity();
                    projectile.position = GetProjectileMuzzlePosition();
                    projectile.rotation = this.target.rotation;
                    projectile.alive = true;
                    break;
                }
            }
        }

        public Vector3 GetProjectileMuzzleVelocity()
        {
            Matrix rotationMatrix =
                Matrix.CreateFromYawPitchRoll(
                    this.target.rotation.Y,
                    this.target.rotation.X,
                    0);

            return Vector3.Normalize(Vector3.Transform(Vector3.Forward, rotationMatrix)) * projectilePower;
        }

        public Vector3 GetProjectileMuzzlePosition()
        {
            return this.target.position + (Vector3.Normalize(GetProjectileMuzzleVelocity()) * muzzleOffset);
        }
    }
}
